#include "Protect.h"
#include "hx6203sys.h"
#include "DataProcess.h"
#include "math.h"

extern uint8_t NodeState[11];

//此函数每秒运行一次
void ProtectLogic(void){
	if(PROTECT_FLAG)            //到达保护功率阈值后开始运行
	{
		uint8_t amp, pa;
		//各告警计数量，任意一路告警计数超过限制，则触发保护
		//PA温度告警计数
		uint8_t PATempResetCount = 0;
		static uint16_t FrontPATempWarnCount[2] = {0}, PATempWarnCount[AMP_NUM][PA_NUM] = {0};
		//PA电流告警计数
		uint8_t PACurrResetCount = 0;
		static uint16_t PACurrWarnCount[AMP_NUM][PA_NUM] = {0};
		//PA电流均衡告警计数
		uint8_t PACurrBalanceResetCount = 0;
		static uint16_t PACurrBalanceWarnCount[AMP_NUM][PA_NUM] = {0};
		
		//刀片温度告警计数
		uint8_t AMPTempResetCount = 0;
		static uint16_t AMPTempWarnCount[AMP_NUM] = {0};
		//刀片电流告警计数
		uint8_t AMPCurrResetCount = 0;
		static uint16_t AMPCurrWarnCount[AMP_NUM] = {0};
		//刀片反射告警计数
		uint8_t AMPReflectResetCount = 0;
		static uint16_t AMPReflectWarnCount[AMP_NUM] = {0};
		//刀片电流均衡告警计数
		uint8_t AMPCurrBalanceResetCount = 0;
		static uint16_t AMPCurrBalanceWarnCount[AMP_NUM] = {0};
		//刀片功率均衡告警计数
		uint8_t AMPRfBalanceResetCount = 0;
		static uint16_t AMPRfBalanceWarnCount[AMP_NUM] = {0};
		
		//整机反射告警计数
		static uint16_t HX6203ReflectWarnCount = 0;
		//增益异常告警
		static uint16_t HX6203GainWarnCount = 0;
		
		float PaAvgTemp=0;
		float PaAvgCurr=0;
		float AMPAvgCurr=0;
		float AMPAvgRf=0;
		float AMPTemp=0,AMPCurr=0;
		
		//遍历九路刀片温度 电流 正向功率 求平均值
		for(amp=0;amp<AMP_NUM;amp++){
			HX6203.AMP[amp].MaxTemp = 0;	//清空上次记录
			for(pa=0;pa<PA_NUM;pa++){
				//计算PA平均温度
				PaAvgTemp+=HX6203.AMP[amp].PA[pa].Temp;
				//计算平均电流
				PaAvgCurr+=HX6203.AMP[amp].PA[pa].Curr;
				//获取刀片内最高PA温度
				if(HX6203.AMP[amp].MaxTemp < HX6203.AMP[amp].PA[pa].Temp)
					HX6203.AMP[amp].MaxTemp = HX6203.AMP[amp].PA[pa].Temp;
			}
			//计算平均正向功率
			AMPAvgRf+=HX6203.AMP[amp].FwdRF;
		}
		AMPAvgCurr = PaAvgCurr/9.0f;
		AMPAvgRf = AMPAvgRf/9.0f;
		PaAvgTemp = PaAvgTemp/27.0f;
		PaAvgCurr = PaAvgCurr/27.0f;
		
		HX6203.PATempMax = HX6203.AMP[0].PA[0].Temp;
		HX6203.PATempMin = HX6203.AMP[0].PA[0].Temp;
		
		//检查前级PA温度
		for(pa=0; pa<2; pa++)
		{
			//如果温度大于保护门限，且之前已经有一次告警，标记错误信息
			if((HX6203.Preamp[pa].Temp>ArbPA250TempErr) && FrontPATempWarnCount[pa])
				BIT_SET(HX6203_Protect, PA250TempProtectBit);
			//如果温度大于告警门限，告警计数量+1，否则清零
			if(HX6203.Preamp[pa].Temp > ArbPA250TempWarn)
			{
				FrontPATempWarnCount[pa]++;
				PATempResetCount++;
			}
			else
				FrontPATempWarnCount[pa] = 0;
			//如果告警计数大于阈值，标记错误信息
			if(FrontPATempWarnCount[pa] > TempWarnDelay)
				BIT_SET(HX6203_Protect, PA250TempProtectBit);
		}
		
		for(amp=0;amp<AMP_NUM;amp++)
		{
			AMPTemp=0;
			AMPCurr=0;
			//判断各PA模块，温度、电流告警保护情况
			for(pa=0;pa<PA_NUM;pa++)
			{
				//记录PA最高温度和最低温度
				if(HX6203.PATempMax < HX6203.AMP[amp].PA[pa].Temp)
					HX6203.PATempMax = HX6203.AMP[amp].PA[pa].Temp;
				if(HX6203.PATempMin > HX6203.AMP[amp].PA[pa].Temp)
					HX6203.PATempMin = HX6203.AMP[amp].PA[pa].Temp;
				
				AMPTemp += HX6203.AMP[amp].PA[pa].Temp;
				AMPCurr += HX6203.AMP[amp].PA[pa].Curr;
				
				//如果温度大于保护门限，且之前已经有一次告警，标记错误信息
				if((HX6203.AMP[amp].PA[pa].Temp>ArbPA250TempErr) && PATempWarnCount[amp][pa])
					BIT_SET(HX6203_Protect, PA250TempProtectBit);
				//如果温度大于告警门限，告警计数量+1，否则清零
				if(HX6203.AMP[amp].PA[pa].Temp > ArbPA250TempWarn)
				{
					PATempWarnCount[amp][pa]++;
					PATempResetCount++;
				}
				else
					PATempWarnCount[amp][pa] = 0;
				//如果告警计数大于阈值，标记错误信息
				if(PATempWarnCount[amp][pa] > TempWarnDelay)
					BIT_SET(HX6203_Protect, PA250TempProtectBit);
				
				//如果电流大于保护门限，且之前已经有一次告警，标记错误信息
				if((HX6203.AMP[amp].PA[pa].Curr>ArbPA250CurrErr) && PACurrWarnCount[amp][pa])
					BIT_SET(HX6203_Protect, PA250CurrProtectBit);
				//如果电流大于告警门限，告警计数量+1，否则清零
				if(HX6203.AMP[amp].PA[pa].Curr > ArbPA250CurrWarn)
				{
					PACurrWarnCount[amp][pa]++;
					PACurrResetCount++;
				}
				else
					PACurrWarnCount[amp][pa]=0;
				//如果告警计数大于阈值，标记错误信息
				if(PACurrWarnCount[amp][pa] > CurrWarnDelay)
					BIT_SET(HX6203_Protect, PA250CurrProtectBit);
				//如果电流差异大于告警门限，告警计数量+1，否则清零
				if(fabs(HX6203.AMP[amp].PA[pa].Curr-PaAvgCurr) > ArbPA250CurrBalanceWarn)
				{
					PACurrBalanceWarnCount[amp][pa]++;
					PACurrBalanceResetCount++;
				}
				else
					PACurrBalanceWarnCount[amp][pa]=0;
				//如果告警计数大于阈值，标记错误信息
				if(PACurrBalanceWarnCount[amp][pa] > CurrWarnDelay)
					BIT_SET(HX6203_Protect, PA250CurrProtectBit);
				//如果电流发生突变则计数器+1，到三时开启保护
				if(((PaAvgCurr - HX6203.AMP[amp].PA[pa].Curr)>ArbPA250CurrBalanceErr) && (NodeState[amp]==NORMAL))
				{
					PACurrBalanceWarnCount[amp][pa]++;
					PACurrBalanceResetCount++;
					if(PACurrBalanceWarnCount[amp][pa] > 3)
						BIT_SET(HX6203_Protect, PA250CurrProtectBit);
				}
				else
					PACurrBalanceWarnCount[amp][pa] = 0;
			}
			//刀片温度、电流、正向功率平衡、反射功率保护
			AMPTemp = AMPTemp/3.0f;//刀片内平均温度
			
			//刀片平均温度超温保护
			if((AMPTemp>AMPTempErr) && AMPTempWarnCount[amp])
				BIT_SET(HX6203_Protect, AMPTempProtectBit);
			if(AMPTemp > AMPTempWarn)
			{
				AMPTempWarnCount[amp]++;
				AMPTempResetCount++;
			}
			else
				AMPTempWarnCount[amp] = 0;
			if(AMPTempWarnCount[amp] > TempWarnDelay)
				BIT_SET(HX6203_Protect, AMPTempProtectBit);
			
			//刀片过电流保护
			if((AMPCurr>AMPCurrErr) && AMPCurrWarnCount[amp])
				BIT_SET(HX6203_Protect, AMPCurrProtectBit);
			if(AMPCurr>AMPCurrWarn)
			{
				AMPCurrWarnCount[amp]++;
				AMPCurrResetCount++;
			}
			else
				AMPCurrWarnCount[amp] = 0;
			if(AMPCurrWarnCount[amp]>CurrWarnDelay)
				BIT_SET(HX6203_Protect, AMPCurrProtectBit);
			
			//刀片电流平衡保护
			if(fabs(AMPCurr-AMPAvgCurr) > AMPCurrBalanceWarn)
			{
				AMPCurrBalanceWarnCount[amp]++;
				AMPCurrBalanceResetCount++;
			}
			else
				AMPCurrBalanceWarnCount[amp]=0;
			if(AMPCurrBalanceWarnCount[amp] > CurrWarnDelay)
				BIT_SET(HX6203_Protect, AMPCurrProtectBit);
		
			//刀片反射功率保护
			if((HX6203.AMP[amp].RevRF > AMPReflectErr) && AMPReflectWarnCount[amp])
				BIT_SET(HX6203_Protect, AMPReflectProtectBit);
			if(HX6203.AMP[amp].RevRF > AMPReflectWarn)
			{
				AMPReflectWarnCount[amp]++;
				AMPReflectResetCount++;
			}
			else
				AMPReflectWarnCount[amp]=0;
			if(AMPReflectWarnCount[amp] > ReflectWarnDelay)
				BIT_SET(HX6203_Protect, AMPReflectProtectBit);
		
			//刀片正向功率平衡保护
			if(fabs(HX6203.AMP[amp].FwdRF-AMPAvgRf) > AMPRfBalanceWarn) 
			{
				AMPRfBalanceWarnCount[amp]++;
				AMPRfBalanceResetCount++;
			}
			else
				AMPRfBalanceWarnCount[amp]=0;
			if(AMPRfBalanceWarnCount[amp] > AMPRfBalanceWarnDelay)
				BIT_SET(HX6203_Protect, AMPRfBalanceProtectBit);

		}
		//整机反射功率保护
		if((HX6203.RevRF>HX6203ReflectErr) && HX6203ReflectWarnCount)
			BIT_SET(HX6203_Protect, HX6203ReflectProtectBit);
		if(HX6203.RevRF>HX6203ReflectWarn)
			HX6203ReflectWarnCount++;
		else
			HX6203ReflectWarnCount=0;
		if(HX6203ReflectWarnCount>ReflectWarnDelay)
			BIT_SET(HX6203_Protect, HX6203ReflectProtectBit);
		
		//整机增益异常保护
		if(fabs(HX6203.FwdRF-HX6203.AimRF) > GainWarn)
			HX6203GainWarnCount++;
		else
			HX6203GainWarnCount=0;
		if(HX6203GainWarnCount > GainWarnDelay)
			BIT_SET(HX6203_Protect, HX6203GainProtectBit);
		else
			BIT_CLEAR(HX6203_Protect, HX6203GainProtectBit);
		
		//状态复位
		if(PATempResetCount == 0)
			BIT_CLEAR(HX6203_Protect, PA250TempProtectBit);
		if(PACurrResetCount == 0)
			BIT_CLEAR(HX6203_Protect, PA250CurrProtectBit);
		if(PACurrBalanceResetCount == 0)
			BIT_CLEAR(HX6203_Protect, PA250CurrProtectBit);
		if(AMPTempResetCount == 0)
			BIT_CLEAR(HX6203_Protect, AMPTempProtectBit); 
		if(AMPCurrResetCount == 0)
			BIT_CLEAR(HX6203_Protect, AMPCurrProtectBit);
		if(AMPCurrBalanceResetCount == 0)
			BIT_CLEAR(HX6203_Protect, AMPCurrProtectBit);
		if(AMPRfBalanceResetCount == 0)
			BIT_CLEAR(HX6203_Protect, AMPRfBalanceProtectBit);
		if(AMPReflectResetCount == 0)
			BIT_CLEAR(HX6203_Protect, AMPReflectProtectBit);
	}
}
